package com.utils 
{
	/**
	 * 计时器工具类;
	 * eStr 事件广播时携带的字符串;
	 * eNum 事件广播时携带的数字;
	 * eArr 事件广播时携带的数组;
	 * eObj 事件广播时携带的关联数组;
	 * cycleNum timer循环已执行的次数;
	 * USER_EVENT 事件类型;
	 * eventDispatcher 事件抛送者，侦听器添加者;
	 * 
	 * @author lufu 
	 */	
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	public class Timepiece extends Event
	{
		/**事件广播时携带的字符串*/
		public var eStr:String;
		
		/**事件广播时携带的数值*/
		public var eNum:Number;
		
		/**事件广播时携带的数组*/
		public var eArr:Array;
		
		/**事件广播时携带的关联数组*/
		public var eObj:Object;
		
		
		
		/**timer循环已执行的次数*/
		public var cycleNum:int;
		
		/**外部回调，与时间同步执行*/
		private var _cycleNumFunc:Function = new Function();
		
		/**事件类型*/		
		public static const TIMEPIECE_EVENT:String = 'TIMEPIECE_EVENT';
		
		/**
		 * 事件抛送者，外部侦听器添加者
		 * 例:
		 * time.eventDispatcher.addEventListener(Timepiece.USER_EVENT,onTimeCompleteHandler);
		 * private function onTimeCompleteHandler(e:Timepiece):void{"计时器停止后要执行的函数"}
		 */
		public var eventDispatcher:EventDispatch = new EventDispatch();
		
		private var _timer:Timer;//计时器
		private var _totalCycle:int;//执行次数
		private var _timerDealy:int;//间隔时间
		
		private var _delayTimer:Timer;//延迟计时器
		private var _isOpenTime:Boolean;//是否立即打开计时器
		private var _delayOpenTime:int;//计时器延迟打开时间
		
		public function Timepiece(type:String = 'TIMEPIECE_EVENT', bubbles:Boolean=false, cancelable:Boolean=false)
		{
			super(type, bubbles, cancelable);
		}
		
		/**
		 * timer 初始化
		 * @param totalCycle 总共执行次数
		 * @param delay 间隔时间
		 * @param isOpenTime 是否立即开启计时器 true：立即开启 false：延迟开启<需设置延迟时间>
		 * @param delayOpenTime 计时器延迟开启时间<单位:毫秒>
		 */		
		public function initTimer(totalCycle:int = 1,delay:int = 1000,
								  isOpenTime:Boolean = true,delayOpenTime:int = 0):void{
			_totalCycle = totalCycle;
			
			_isOpenTime = isOpenTime;
			_delayOpenTime = delayOpenTime;
			
			if(_timer) clearTimer();
			
			_timer = new Timer(delay,1);
			_timer.addEventListener(TimerEvent.TIMER_COMPLETE,onTimerCompleteHandler);
			
			if(_isOpenTime){//立即打开
				openTimer()
			}else if(!_isOpenTime && _delayOpenTime > 0){//延迟打开
				setDelayOpen();
			}
			
		}
		
		/**设置计时器开启时间*/		
		private function setDelayOpen():void
		{
			_delayTimer = new Timer(_delayOpenTime,1);
			_delayTimer.addEventListener(TimerEvent.TIMER_COMPLETE,onDelayCompleteHandler);
			_delayTimer.start();
		}
		
		/**清理_delayTimer,延迟时间结束，开启计时器*/		
		private function onDelayCompleteHandler(e:TimerEvent):void
		{
			_delayTimer.stop();
			_delayTimer.removeEventListener(TimerEvent.TIMER_COMPLETE,onDelayCompleteHandler);
			_delayTimer = null;
			openTimer();
		}
		
		/**手动开启Timer计数器,如果已设置延迟开启,无需在调用此方法,否则延迟设置无效*/		
		public function openTimer():void{
			if(!_timer){
				throw Error('timer不存在,请先创建,在开启!');
				return;
			}
			
			_timer.start();
		}
		
		private function onTimerCompleteHandler(event:TimerEvent):void
		{
			if(cycleNum < _totalCycle){
				cycleNum++;
				_cycleNumFunc();
				_timer.stop();
				_timer.start();
				//trace('第' + cycleNum + '次循环！');
			}else{
				clearTimer();//清理timer
				eventDispatcher.eventDispatch(eStr,eNum,eArr,eObj);
			}
		}	
		
		/**清理timer*/		
		private function clearTimer():void{
			_timer.stop();
			_timer.removeEventListener(TimerEvent.TIMER_COMPLETE,onTimerCompleteHandler);
			_timer = null;
		}
		
		/**
		 * 回调函数，与timer循环周期同步,外部可设置回调方法,与时间同步执行; 
		 * @param value 外部要执行的方法
		 */		
		public function set cycleNumFunc(value:Function):void{_cycleNumFunc = value;}
		
		/**设置间隔时间*/
		public function set timerDealy(value:int):void{
			_timer.delay = _timerDealy;
			_timerDealy = value;
		}
		
		
	}
}

import com.utils.Timepiece;

import flash.events.EventDispatcher;

class EventDispatch extends EventDispatcher{
	/**广播*/		
	public function eventDispatch(uEMsg:String = null,uENum:Number = NaN,uEArr:Array = null,uEObj:Object = null):void{
		var timepiece:Timepiece = new Timepiece(Timepiece.TIMEPIECE_EVENT);
		timepiece.eStr = uEMsg;
		timepiece.eNum = uENum;
		timepiece.eArr = uEArr;
		timepiece.eObj = uEObj;
		dispatchEvent(timepiece);
	}
}
